package com.atwy.linearstructure.queue;

import java.util.Scanner;

/**
 *
 */
public class CircleQueueDemo {
    public static void main(String[] args) {
        CircleQueue queue = new CircleQueue(4);
        char key = ' ';
        Scanner scanner = new Scanner(System.in);
        boolean loop = true;
        while (loop) {
            System.out.println("s(showAll): 显示队列有效数据");
            System.out.println("e(exit): 退出程序");
            System.out.println("a(add): 添加数据到队列");
            System.out.println("g(get): 从队列取出数据");
            System.out.println("h(head): 查看队列头的数据");
            key = scanner.next().charAt(0);// 接收一个字符
            switch (key) {
                case 's':
                    queue.printAll();
                    break;
                case 'a':
                    System.out.println("请输入一个数字");
                    int value = scanner.nextInt();
                    queue.enqueue(value);
                    break;
                case 'g':
                    try {
                        int res = queue.dequeue();
                        System.out.printf("取出的数据是%d\n", res);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'h':
                    try {
                        int headValue = queue.lookHead();
                        System.out.printf("队列头的数据是%d\n", headValue);
                    } catch (Exception e) {
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'e':
                    scanner.close();
                    loop = false;
                    break;
                default:break;
            }
            System.out.println();
        }
        System.out.println("程序已退出~");
    }
}

class CircleQueue {
    /**
     * 总数
     */
    private int maxSize;

    /**
     * 指向队列的第一个元素，初始值为0
     */
    private int front;

    /**
     * 指向队列最后一个元素的下一个位置，初始值为0
     */
    private int rear;

    /**
     * 存储数据的数组
     */
    private int[] container;

    public CircleQueue(int maxSize) {
        this.maxSize = maxSize;
        container = new int[this.maxSize];
    }

    /**
     * 队列是否已满
     *
     * @return
     */
    public boolean isFull() {
        return (rear + 1) % maxSize == front;
    }

    /**
     * 队列是否为空
     *
     * @return
     */
    public boolean isEmpty() {
        return front == rear;
    }

    /**
     * 入队，需要判断队列是否已满
     *
     * @param value
     */
    public void enqueue(int value) {
        if (isFull()) {
            System.out.println("队列已满~");
            return;
        }
        container[rear] = value;
        // 空一个位置，加1后对数组长度取模即可完成环形取值
        rear = (rear + 1) % maxSize;
    }

    /**
     * 出队列，需要判断队列是否为空
     *
     * @return
     */
    public int dequeue() {
        if (isEmpty()) {
            throw new RuntimeException("队列无数据可取");
        }
        int result = container[front];
        front = (front + 1) % maxSize;
        return result;
    }

    /**
     * 查看队列头的第一个元素
     *
     * @return
     */
    public int lookHead() {
        if (isEmpty()) {
            throw new RuntimeException("队列无数据");
        }
        return container[front];
    }

    /**
     * 打印队列中的元素
     */
    public void printAll() {
        /*int sum = 0;
        for (int i = front; sum < size(); ) {
            System.out.println(container[i]);
            i = (i + 1) % maxSize;
            sum++;
        }*/
        for (int i = front; i < front + size(); i++) {
            System.out.printf("arr[%d] = %d\n", i % maxSize, container[i % maxSize]);
        }
    }

    /**
     * 队列中有效元素的个数
     *
     * @return
     */
    public int size() {
        return (rear + maxSize - front) % maxSize;
    }

}
